package com.ruoyi.yipaiju.utils;

import cn.hutool.core.convert.Convert;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.draw.SolidLine;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.borders.Border;
import com.itextpdf.layout.element.*;
import com.itextpdf.layout.properties.HorizontalAlignment;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.UnitValue;
import com.ruoyi.common.enums.DueDiligenceReportEnums;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.yipaiju.domain.vo.CommonEntityVO;
import com.ruoyi.yipaiju.domain.vo.ReportResultVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 尽职调查报告PDF生成工具类（兼容Windows/Linux跨平台）
 * 使用iText库生成PDF文档，支持中文字体显示，处理网络和本地图片
 */
public class DueDiligenceReportGenerator {

    // ============================ 常量定义（统一维护）============================
    /** 日志对象 */
    private static final Logger log = LoggerFactory.getLogger(DueDiligenceReportGenerator.class);

    /** 内置字体路径（项目resources目录下，跨平台通用） */
    private static final String INTERNAL_FONT_PATH = "fonts/SimHei.ttf";
    private static final String SYSTEM_FONT_WINDOWS = "C:/Windows/Fonts/simhei.ttf";
    private static final String SYSTEM_FONT_LINUX = "/usr/share/fonts/my_fonts/simhei.ttf";


    /** 网络图片正则（支持http/https链接） */
    private static final Pattern WEB_IMAGE_PATTERN = Pattern.compile("^https?://.*\\.(jpg|jpeg|png|gif|bmp|webp)$", Pattern.CASE_INSENSITIVE);

    /** PDF页面尺寸（A4） */
    private static final PageSize PDF_PAGE_SIZE = PageSize.A4;

    /** 表格默认列宽（百分比，适配不同阅读器） */
    private static final float[] DEFAULT_TABLE_COL_WIDTHS = {30, 70}; // 3:7比例，左列标题，右列内容

    /** 标题字体大小 */
    private static final float TITLE_FONT_SIZE = 18f;

    /** 副标题字体大小 */
    private static final float SUB_TITLE_FONT_SIZE = 14f;

    /** 正文字体大小 */
    private static final float CONTENT_FONT_SIZE = 12f;

    /** 页眉/页脚字体大小 */
    private static final float HEADER_FOOTER_FONT_SIZE = 10f;


    /**
     * 生成尽职调查报告PDF（对外统一入口）
     * @param dest PDF输出路径（如：D:/report.pdf 或 /home/report.pdf）
     * @param reportData 报告数据（key：报告类型枚举code，value：对应模块数据）
     * @throws IOException 当文件写入、字体加载、图片加载失败时抛出
     */
    public static void createPdf(String dest, Map<String, Object> reportData) throws IOException {
        // 1. 校验输入参数
        validateInput(dest, reportData);

        // 2. 初始化PDF核心对象（try-with-resources自动关闭资源）
        try (PdfWriter writer = new PdfWriter(dest);
             PdfDocument pdfDoc = new PdfDocument(writer);
             Document document = new Document(pdfDoc, PDF_PAGE_SIZE)) {

            // 3. 加载中文字体（跨平台兼容）
            PdfFont chineseFont = loadChineseFont();

            // 4. 按顺序生成PDF各页面
            generateReportPages(document, chineseFont, reportData);

            log.info("尽职调查报告生成成功！输出路径：{}", dest);
        } catch (Exception e) {
            log.error("生成尽职调查报告异常！输出路径：{}，异常信息：", dest, e);
            throw new IOException("PDF生成失败：" + e.getMessage(), e);
        }
    }
    // ============================ 核心流程方法 =============================
    /**
     * 校验输入参数合法性
     */
    private static void validateInput(String dest, Map<String, Object> reportData) {
        if (dest == null || dest.trim().isEmpty()) {
            throw new IllegalArgumentException("PDF输出路径不能为空！");
        }
        if (reportData == null || reportData.isEmpty()) {
            throw new IllegalArgumentException("报告数据不能为空！");
        }
    }
    /**
     * 加载中文字体（跨平台兼容：优先加载内置字体，失败则使用系统默认字体）
     * JDK8兼容版本
     */
    private static PdfFont loadChineseFont() throws IOException {
        // 1. 通过Spring上下文工具类获取FontTestRunner实例
        FontTestRunner fontTestRunner = SpringUtils.getBean(FontTestRunner.class);
        // 2. 调用方法获取字体资源
        Resource fontResource = fontTestRunner.getFontResource();
        // 3. 使用资源（例如获取输入流）
        if (fontResource.exists()) {
            try (InputStream inputStream = fontResource.getInputStream()) {
                if (inputStream != null) {
                    log.info("正在加载内置中文字体：{},大小：{}", INTERNAL_FONT_PATH, inputStream.available());
                    // JDK8不支持InputStream.readAllBytes()，使用自定义方法读取
//                    byte[] fontBytes = readInputStreamToBytes(inputStream);
                    return PdfFontFactory.createFont(
                            INTERNAL_FONT_PATH,
                            PdfEncodings.IDENTITY_H,
                            PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED // 嵌入字体，避免依赖目标设备
                    );
                }
            } catch (IOException e) {
                log.warn("内置字体加载失败，尝试使用系统字体！异常信息：", e);
            }
        }
        log.info("加载中文字体");

        // 2. 内置字体加载失败，降级使用系统字体（兼容Win/Linux）
        String osName = System.getProperty("os.name").toLowerCase();
        String systemFontPath = osName.contains("win")
                ? SYSTEM_FONT_WINDOWS
                : SYSTEM_FONT_LINUX; // Linux需提前安装中文字体

        try {
            log.info("正在加载系统字体：{}", systemFontPath);
            return PdfFontFactory.createFont(systemFontPath, PdfEncodings.IDENTITY_H);
        } catch (IOException e) {
            log.error("系统字体加载失败！请确认字体文件存在：{}", systemFontPath);
            throw new IOException("中文字体加载失败：内置字体与系统字体均不可用", e);
        }
    }


    /**
     * JDK8兼容：将InputStream转换为byte数组
     */
    private static byte[] readInputStreamToBytes(InputStream inputStream) throws IOException {
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            // 循环读取输入流内容到缓冲区
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            return outputStream.toByteArray();
        }
    }

    /**
     * 按顺序生成PDF各页面（封面、前言、基础信息等）
     */
    private static void generateReportPages(Document document, PdfFont font, Map<String, Object> reportData) {
        // 1. 封面页（若有数据则生成）
        ReportResultVO coverData =  Convert.convert(ReportResultVO.class,reportData.get(DueDiligenceReportEnums.COVER.getCode()));
        if (coverData != null) {
            createCoverPage(document, font, coverData);
        }

        // 2. 前言页
        createPrefacePage(document, font,  Convert.convert(ReportResultVO.class,reportData.get(DueDiligenceReportEnums.FRONTIER.getCode())));

        // 3. 标的物基础信息页
        createBasicInfoPage(document, font,  Convert.convert(ReportResultVO.class,reportData.get(DueDiligenceReportEnums.BASICINFO.getCode())));

        // 4. 标的物拍卖信息页
        createAuctionInfoPage(document, font,  Convert.convert(ReportResultVO.class,reportData.get(DueDiligenceReportEnums.AUCTIONINFO.getCode())));

        // 5. 图像信息页
        createImageInfoPage(document, font,  Convert.convert(ReportResultVO.class,reportData.get(DueDiligenceReportEnums.IMAGEINFO.getCode())), Convert.toList(String.class,reportData.get(DueDiligenceReportEnums.IMAGEINFOS.getCode())));

        // 6. 标的物周边配套信息页
        createSurroundingInfoPage(document, font,  Convert.convert(ReportResultVO.class,reportData.get(DueDiligenceReportEnums.VALUERESEARCH.getCode())));

        // 7. 标的物权属信息页
        createPropertyRightInfoPage(document, font,  Convert.convert(ReportResultVO.class,reportData.get(DueDiligenceReportEnums.OWNERSHIPINFO.getCode())));

        // 8. 标的物费用信息页
        createCostInfoPage(document, font,  Convert.convert(ReportResultVO.class,reportData.get(DueDiligenceReportEnums.COSTINFO.getCode())));

        // 9. 标的物风险信息页
        createRiskInfoPage(document, font,  Convert.convert(ReportResultVO.class,reportData.get(DueDiligenceReportEnums.RISKINFO.getCode())));
    }


    // ============================ 页面生成方法（按模块拆分）============================
    /**
     * 生成封面页
     */
    private static void createCoverPage(Document document, PdfFont font, ReportResultVO coverData1) {
        addPageHeader(document, font);

        // 1. 公司Logo（优先使用数据中的图片路径，无则用默认）
//        String logoPath = coverData.getValues() != null && !coverData.getValues().isEmpty()
//                ? coverData.getValues().get(0).getValue()
//                : "D://微信截图_20250730151444.png"; // 默认Logo路径（可配置化）
        addImageToDocument(document, font, "", true);
        // 2. 报告标题
        Paragraph title = new Paragraph("尽职调查报告")
                .setFont(font)
                .setFontSize(36f)
                .setBold()
                .setTextAlignment(TextAlignment.CENTER)
                .setMarginTop(20f);
        document.add(title);
        // 3. 标的物信息
//        String subjectInfo = coverData.getValues() != null && coverData.getValues().size() > 1
//                ? coverData.getValues().get(1).getValue()
//                : "标的物：未指定";
        String subjectInfo = "标的物：番禺区小谷围街求真街110号13栋1202房【（2021）粤2071执恢2261号】";

        Paragraph subject = new Paragraph(subjectInfo)
                .setFont(font)
                .setFontSize(SUB_TITLE_FONT_SIZE)
                .setTextAlignment(TextAlignment.CENTER)
                .setMarginTop(30f);
        document.add(subject);

        // 4. 信息分类表格
        Table infoTable = createTable(DEFAULT_TABLE_COL_WIDTHS, font);
        infoTable.setMarginTop(80f);
        infoTable.setHorizontalAlignment(HorizontalAlignment.CENTER);
        infoTable.addCell(createInfoCell("标的物基础信息", font));
        infoTable.addCell(createInfoCell("标的物权属信息", font));
        infoTable.addCell(createInfoCell("标的物费用信息", font));
        infoTable.addCell(createInfoCell("标的物风险信息", font));
        document.add(infoTable);

        // 5. 页脚（公司信息）
        Paragraph footer = new Paragraph("广州易拍居信息服务有限公司")
                .setFont(font)
                .setFontSize(HEADER_FOOTER_FONT_SIZE)
                .setBold()
                .setTextAlignment(TextAlignment.CENTER)
                .setFixedPosition(
                        40f,
                        30f,
                        document.getPdfDocument().getDefaultPageSize().getWidth() - 80f
                );
        document.add(footer);

        // 分页
        document.add(new AreaBreak());
    }

    /**
     * 生成前言页
     */
    private static void createPrefacePage(Document document, PdfFont font, ReportResultVO frontierData) {
        if (frontierData == null) {
            log.warn("前言页数据为空，跳过生成！");
            return;
        }

        addPageHeader(document, font);
        // 前言标题
        Paragraph title = new Paragraph(frontierData.getComment())
                .setFont(font)
                .setFontSize(TITLE_FONT_SIZE)
                .setBold()
                .setTextAlignment(TextAlignment.CENTER)
                .setMarginTop(30f);
        document.add(title);

        // 前言内容（解决空格无法显示问题：使用首行缩进）
        Paragraph content = new Paragraph()
                .setFont(font)
                .setFontSize(CONTENT_FONT_SIZE)
                .setTextAlignment(TextAlignment.LEFT)
                .setMargin(20f)
                .setFirstLineIndent(24f)
                .setMarginLeft(25); // 首行缩进2字符（1字符=12f）
        content.add(frontierData.getValue());
        document.add(content);

        // 版权声明
        Paragraph copyright = new Paragraph("本尽职调查报告所有内容最终解释权归广州易拍居信息服务有限公司所有")
                .setFont(font)
                .setFontSize(CONTENT_FONT_SIZE)
                .setTextAlignment(TextAlignment.CENTER)
                .setMarginTop(30f);
        document.add(copyright);

        document.add(new AreaBreak());
    }

    /**
     * 生成标的物基础信息页
     */
    private static void createBasicInfoPage(Document document, PdfFont font, ReportResultVO basicInfoData) {
        if (basicInfoData == null || basicInfoData.getValues() == null) {
            log.warn("标的物基础信息数据为空，跳过生成！");
            return;
        }
        addPageHeader(document, font);
        // 页面标题
        Paragraph title = new Paragraph("标的物基础信息")
                .setFont(font)
                .setFontSize(TITLE_FONT_SIZE)
                .setBold()
                .setTextAlignment(TextAlignment.CENTER)
                .setMarginBottom(15f);
        document.add(title);
        // 表格标题
        Paragraph tableTitle = new Paragraph("标的物基础信息表")
                .setFont(font)
                .setFontSize(SUB_TITLE_FONT_SIZE)
                .setBold()
                .setTextAlignment(TextAlignment.LEFT)
                .setMarginBottom(10f)
                .setMarginLeft(25);
        document.add(tableTitle);

        // 生成基础信息表格
        Table basicTable = createDataTable(font, basicInfoData.getValues(), "标的物基础信息");
        document.add(basicTable);
        document.add(new AreaBreak());
    }

    /**
     * 生成标的物拍卖信息页
     */
    private static void createAuctionInfoPage(Document document, PdfFont font, ReportResultVO auctionInfoData) {
        if (auctionInfoData == null || auctionInfoData.getValues() == null) {
            log.warn("标的物拍卖信息数据为空，跳过生成！");
            return;
        }

        addPageHeader(document, font);

        // 表格标题
        Paragraph tableTitle = new Paragraph(auctionInfoData.getComment())
                .setFont(font)
                .setFontSize(SUB_TITLE_FONT_SIZE)
                .setBold()
                .setTextAlignment(TextAlignment.LEFT)
                .setMarginBottom(10f)
                .setMarginLeft(25);
        document.add(tableTitle);

        // 生成拍卖信息表格
        Table auctionTable = createDataTable(font, auctionInfoData.getValues(), auctionInfoData.getComment());
        document.add(auctionTable);

        document.add(new AreaBreak());
    }

    /**
     * 生成图像信息页（支持网络图片与本地图片）
     */
    private static void createImageInfoPage(Document document, PdfFont font, ReportResultVO imageInfoData, List<String> imageInfos) {
        if ((imageInfoData == null || imageInfoData.getValues() == null || imageInfoData.getValues().isEmpty()) && imageInfos.size() == 0) {
            log.warn("图像信息数据为空，跳过生成！");
            return;
        }
        try {
            addPageHeader(document, font);
            // 图片信息标题（预留）
            Paragraph imgTitle = new Paragraph("标的物图片信息")
                    .setFont(font)
                    .setFontSize(SUB_TITLE_FONT_SIZE)
                    .setBold()
                    .setTextAlignment(TextAlignment.LEFT)
                    .setMarginTop(20f)
                    .setMarginLeft(25);
            document.add(imgTitle);
            // 页面标题
            Paragraph title = new Paragraph("标的物图像信息")
                    .setFont(font)
                    .setFontSize(SUB_TITLE_FONT_SIZE)
                    .setBold()
                    .setTextAlignment(TextAlignment.CENTER)
                    .setMarginBottom(20f);
            document.add(title);
        //确认是否有图片
        List<CommonEntityVO> imageList = imageInfoData.getValues();
        List<String> images = new ArrayList<>();
        for (int i = 0; i < imageList.size(); i++) {
            CommonEntityVO imageEntity = imageList.get(i);
            String imagePath = imageEntity.getValue();
            if (!"".equals(imagePath.trim()) && imagePath != null) {
                images.add(imagePath.trim());
            }
        }
        if(images.size() > 0){
            // 遍历所有图片地址，逐张生成图片页
            for (int i = 0; i < images.size(); i++) {
                String imagePath = images.get(i);
                // 加载并添加图片（支持网络/本地图片）
                addImageToDocument(document, font, imagePath, false);
//                CommonEntityVO imageEntity = imageList.get(i);
//                String imagePath = imageEntity.getValue();
//                if (imagePath == null || imagePath.trim().isEmpty()) {
//                    log.warn("第{}张图片路径为空，跳过加载！", i + 1);
//                    continue;
//                }
//            //添加图片描述（如"图1：标的物外观"）
//            Paragraph imageDesc = new Paragraph(String.format("图%d：%s", i + 1, imageEntity.getComment()))
//                    .setFont(font)
//                    .setFontSize(CONTENT_FONT_SIZE)
//                    .setTextAlignment(TextAlignment.CENTER)
//                    .setMarginBottom(10f);
//            document.add(imageDesc);
//                // 加载并添加图片（支持网络/本地图片）
//                addImageToDocument(document, font, imagePath, false);
//                // 非最后一张图片，添加分页（避免多图挤在同一页）
//                if (i != imageList.size() - 1) {
//                    document.add(new AreaBreak());
//                    addPageHeader(document, font); // 新页面重新添加页眉
//                }
            }
        }else {
            // 遍历所有图片地址，逐张生成图片页
            for (int i = 0; i < imageInfos.size(); i++) {
                String imagePath = imageInfos.get(i);
                // 加载并添加图片（支持网络/本地图片）
                addImageToDocument(document, font, imagePath, false);
            }
        }
            document.add(new AreaBreak());
        }catch (Exception e){
            log.info("图片解析错误：{}", e.getMessage());
        }

    }

    /**
     * 生成标的物周边配套信息页
     */
    private static void createSurroundingInfoPage(Document document, PdfFont font, ReportResultVO surroundingData) {
        if (surroundingData == null || surroundingData.getValues() == null) {
            log.warn("周边配套信息数据为空，跳过生成！");
            return;
        }
        addPageHeader(document, font);
        // 页面标题
        Paragraph title = new Paragraph("标的物周边配套信息")
                .setFont(font)
                .setFontSize(TITLE_FONT_SIZE)
                .setBold()
                .setTextAlignment(TextAlignment.CENTER)
                .setMarginBottom(15f);
        document.add(title);

        // 表格标题
        Paragraph tableTitle = new Paragraph(surroundingData.getComment())
                .setFont(font)
                .setFontSize(SUB_TITLE_FONT_SIZE)
                .setBold()
                .setTextAlignment(TextAlignment.LEFT)
                .setMarginBottom(10f)
                .setMarginLeft(25);
        document.add(tableTitle);

        // 生成周边配套表格
        Table surroundingTable = createDataTable(font, surroundingData.getValues(), "周边配套信息表");
        document.add(surroundingTable);

        // 价格走势模块（预留，可后续扩展图表生成）
        Paragraph priceTitle = new Paragraph("价格走势参考")
                .setFont(font)
                .setFontSize(SUB_TITLE_FONT_SIZE)
                .setBold()
                .setTextAlignment(TextAlignment.LEFT)
                .setMarginTop(20f)
                .setMarginLeft(25);
        document.add(priceTitle);

        Paragraph priceHint = new Paragraph("注：价格走势数据需结合第三方房产平台接口获取，当前显示为示例格式（可扩展ECharts图表导出）")
                .setFont(font)
                .setFontSize(CONTENT_FONT_SIZE - 2f)
                .setTextAlignment(TextAlignment.LEFT)
                .setMarginTop(5f)
                .setMarginLeft(25)
                .setFontColor(ColorConstants.GRAY);
        document.add(priceHint);

        document.add(new AreaBreak());
    }

    /**
     * 生成标的物权属信息页
     */
    private static void createPropertyRightInfoPage(Document document, PdfFont font, ReportResultVO ownershipData) {
        if (ownershipData == null || ownershipData.getValues() == null) {
            log.warn("权属信息数据为空，跳过生成！");
            return;
        }

        addPageHeader(document, font);

        // 页面标题
        Paragraph title = new Paragraph("标的物权属信息")
                .setFont(font)
                .setFontSize(TITLE_FONT_SIZE)
                .setBold()
                .setTextAlignment(TextAlignment.CENTER)
                .setMarginBottom(15f);
        document.add(title);

        // 拆分权属表格数据与查册图片数据（按code区分）
        CommonEntityVO propertyTableData = null;
        CommonEntityVO propertyImageData = null;
        for (CommonEntityVO entity : ownershipData.getValues()) {
            if ("propertyTable".equals(entity.getCode())) {
                propertyTableData = entity;
            } else if ("propertyImages".equals(entity.getCode())) {
                propertyImageData = entity;
            }
        }

        // 1. 生成权属信息表格
        if (propertyTableData != null && propertyTableData.getValues() != null) {
            Paragraph tableTitle = new Paragraph(propertyTableData.getComment())
                    .setFont(font)
                    .setFontSize(SUB_TITLE_FONT_SIZE)
                    .setBold()
                    .setTextAlignment(TextAlignment.LEFT)
                    .setMarginBottom(10f)
                    .setMarginLeft(25);
            document.add(tableTitle);

            Table ownershipTable = createDataTable(font, propertyTableData.getValues(), "权属信息明细");
            document.add(ownershipTable);
        }

        // 2. 生成不动产查册图片
        if (propertyImageData != null && propertyImageData.getValues() != null) {
            //判断是否有图片
            List<String> imageList = new ArrayList();
            for (CommonEntityVO imageEntity : propertyImageData.getValues()) {
                if(!"".equals(imageEntity.getValue()) && imageEntity.getValue() != null){
                    imageList.add(imageEntity.getValue());
                }
            }
            if(imageList.size() > 0){
                document.add(new AreaBreak()); // 图片单独分页
                addPageHeader(document, font);
                Paragraph imageTitle = new Paragraph(propertyImageData.getComment())
                        .setFont(font)
                        .setFontSize(SUB_TITLE_FONT_SIZE)
                        .setBold()
                        .setTextAlignment(TextAlignment.CENTER)
                        .setMarginBottom(15f);
                document.add(imageTitle);
                // 加载查册图片（支持多张）
                for (String imagePath : imageList) {
                    addImageToDocument(document, font, imagePath, false);
                }
            }
        }

        document.add(new AreaBreak());
    }

    /**
     * 生成标的物费用信息页
     */
    private static void createCostInfoPage(Document document, PdfFont font, ReportResultVO costData) {
        if (costData == null || costData.getValues() == null) {
            log.warn("费用信息数据为空，跳过生成！");
            return;
        }

        addPageHeader(document, font);

        // 页面标题
        Paragraph title = new Paragraph("标的物费用信息")
                .setFont(font)
                .setFontSize(TITLE_FONT_SIZE)
                .setBold()
                .setTextAlignment(TextAlignment.CENTER)
                .setMarginBottom(15f);
        document.add(title);

        // 表格标题
        Paragraph tableTitle = new Paragraph("标的物税费测算表")
                .setFont(font)
                .setFontSize(SUB_TITLE_FONT_SIZE)
                .setBold()
                .setTextAlignment(TextAlignment.LEFT)
                .setMarginBottom(10f)
                .setMarginLeft(25);
        document.add(tableTitle);

        // 生成税费测算表格
        Table costTable = createDataTable(font, costData.getValues(), "税费明细");
        document.add(costTable);

        // 税费说明备注
        Paragraph taxRemark = new Paragraph()
                .setFont(font)
                .setFontSize(CONTENT_FONT_SIZE - 2f)
                .setTextAlignment(TextAlignment.LEFT)
                .setMarginTop(15f)
                .setMarginLeft(25)
                .add("备注：\n")
                .add("1. 增值税及附加：普通住宅不满五年按拍卖成交价款的5.3%征收，满五年免征；\n")
                .add("2. 契税：受让方首套90㎡以内1%、90㎡以上1.5%，二套统一3%；\n")
                .add("3. 个人所得税：转让自用满五年家庭唯一住房免征；能提供原值凭证的按“（计税金额-房产原值-合理费用）×20%”征收；无法提供原值凭证的按拍卖成交价×3%征收；\n")
                .add("4. 本税费核算为易拍居根据税局政策预估，实际税费以税局核税结果为准。");
        document.add(taxRemark);

        document.add(new AreaBreak());
    }

    /**
     * 生成标的物风险信息页
     */
    private static void createRiskInfoPage(Document document, PdfFont font, ReportResultVO riskData) {
        if (riskData == null || riskData.getValues() == null) {
            log.warn("风险信息数据为空，跳过生成！");
            return;
        }

        addPageHeader(document, font);

        // 页面标题
        Paragraph title = new Paragraph("标的物风险信息")
                .setFont(font)
                .setFontSize(TITLE_FONT_SIZE)
                .setBold()
                .setTextAlignment(TextAlignment.CENTER)
                .setMarginBottom(15f);
        document.add(title);

        // 拆分基础风险数据与风险评级数据（按code区分）
        CommonEntityVO basicRiskData = null;
        CommonEntityVO riskRatingData = null;
        for (CommonEntityVO entity : riskData.getValues()) {
            if ("basicRiskInfo".equals(entity.getCode())) {
                basicRiskData = entity;
            } else if ("riskRating".equals(entity.getCode())) {
                riskRatingData = entity;
            }
        }

        // 1. 生成基础风险信息表格
        if (basicRiskData != null && basicRiskData.getValues() != null) {
            Paragraph tableTitle = new Paragraph(basicRiskData.getComment())
                    .setFont(font)
                    .setFontSize(SUB_TITLE_FONT_SIZE)
                    .setBold()
                    .setTextAlignment(TextAlignment.LEFT)
                    .setMarginBottom(10f)
                    .setMarginLeft(25);
            document.add(tableTitle);

            Table basicRiskTable = createDataTable(font, basicRiskData.getValues(), "基础风险明细");
            document.add(basicRiskTable);
        }

        // 2. 生成风险评级模块
        if (riskRatingData != null && riskRatingData.getValues() != null) {
            Paragraph ratingTitle = new Paragraph( riskRatingData.getComment())
                    .setFont(font)
                    .setFontSize(SUB_TITLE_FONT_SIZE)
                    .setBold()
                    .setTextAlignment(TextAlignment.LEFT)
                    .setMarginTop(20f)
                    .setMarginLeft(25);
            document.add(ratingTitle);

            // 风险评级结果（突出显示）
            Paragraph ratingResult = new Paragraph("易拍居-尽职调查风控评级：A（较低风险）")
                    .setFont(font)
                    .setFontSize(CONTENT_FONT_SIZE)
                    .setBold()
                    .setTextAlignment(TextAlignment.LEFT)
                    .setMarginTop(5f)
                    .setMarginLeft(25)
                    .setFontColor(ColorConstants.BLUE);
            document.add(ratingResult);

            // 风险评级明细表格
            Table ratingTable = createDataTable(font, riskRatingData.getValues(), "风险评级标准");
            document.add(ratingTable);
        }

        // 3. 现场调查信息
        Paragraph surveyTitle = new Paragraph("现场调查信息")
                .setFont(font)
                .setFontSize(SUB_TITLE_FONT_SIZE)
                .setBold()
                .setTextAlignment(TextAlignment.LEFT)
                .setMarginTop(20f)
                .setMarginLeft(25);
        document.add(surveyTitle);

        Paragraph surveyContent = new Paragraph("物业管理严格，调查人员未能入楼调查。建议竞拍前联系物业确认入户查看流程。")
                .setFont(font)
                .setFontSize(CONTENT_FONT_SIZE)
                .setTextAlignment(TextAlignment.LEFT)
                .setMarginTop(5f)
                .setMarginLeft(25);
        document.add(surveyContent);

        // 4. 免责声明（底部固定）
        Paragraph disclaimer = new Paragraph()
                .setFont(font)
                .setFontSize(CONTENT_FONT_SIZE - 1f)
                .setTextAlignment(TextAlignment.LEFT)
                .setMarginTop(30f)
                .setMarginLeft(25)
                .add("免责声明：\n")
                .add("本《尽职调查报告》依据《拍卖法》《最高人民法院关于人民法院网络司法拍卖的规定》及相关协议生成，以送拍机构公示信息为基础，通过大数据、现场走访及部门咨询梳理信息并提供风险提示。\n")
                .add("本报告内容仅供竞拍参考，不构成投资建议；最终解释权归广州易拍居信息服务有限公司所有。");
        document.add(disclaimer);
    }


    // ============================ 通用工具方法（复用性优化）============================
    /**
     * 添加页面页眉（统一格式：公司名称+分隔线）
     */
    private static void addPageHeader(Document document, PdfFont font) {
        // 公司名称
        Paragraph companyPara = new Paragraph("广州易拍居信息服务有限公司 - 尽职调查报告")
                .setFont(font)
                .setFontSize(HEADER_FOOTER_FONT_SIZE)
                .setTextAlignment(TextAlignment.CENTER)
                .setMarginTop(5f);
        document.add(companyPara);

        // 分隔线（统一样式）
        LineSeparator separator = new LineSeparator(new SolidLine());
        separator.setMarginTop(5f);
        separator.setMarginBottom(15f);
        document.add(separator);
    }

    /**
     * 创建通用数据表格（左列标题+右列内容，支持表头）
     * @param font 字体
     * @param dataList 表格数据（CommonEntityVO：comment=标题，value=内容）
     * @param headerText 表头文本（可为空，空则不显示表头）
     * @return 配置好的Table对象
     */
    private static Table createDataTable(PdfFont font, List<CommonEntityVO> dataList, String headerText) {
        // 表格列宽（百分比，适配A4页面）
        Table table = new Table(UnitValue.createPercentArray(DEFAULT_TABLE_COL_WIDTHS));
        table.setWidth(UnitValue.createPercentValue(90f)); // 表格宽度占页面90%
        table.setHorizontalAlignment(HorizontalAlignment.CENTER); // 表格居中
        table.setMarginBottom(10f);

        // 添加表头（若有）
        if (headerText != null && !headerText.trim().isEmpty()) {
            Cell headerCell = new Cell(1, 2)
                    .add(new Paragraph(headerText)
                            .setFont(font)
                            .setFontSize(CONTENT_FONT_SIZE)
                            .setBold()
                            .setTextAlignment(TextAlignment.CENTER))
                    .setBackgroundColor(ColorConstants.LIGHT_GRAY)
                    .setMargin(5f);
            table.addHeaderCell(headerCell);
        }

        // 添加表格内容
        for (CommonEntityVO data : dataList) {
            // 左列：标题（加粗）
            Cell titleCell = new Cell()
                    .add(new Paragraph(data.getComment())
                            .setFont(font)
                            .setFontSize(CONTENT_FONT_SIZE)
                            .setBold())
//                    .setBorder(Border.NO_BORDER)
                    .setMargin(8f);
            table.addCell(titleCell);

            // 右列：内容（支持换行）
            Cell contentCell = new Cell()
                    .add(new Paragraph(data.getValue())
                            .setFont(font)
                            .setFontSize(CONTENT_FONT_SIZE))
//                    .setBorder(Border.NO_BORDER)
                    .setMargin(8f);
            table.addCell(contentCell);
        }

        return table;
    }

    /**
     * 加载并添加图片到文档（支持网络图片/本地图片，自动适配尺寸）
     * @param document PDF文档对象
     * @param font 字体（用于错误提示）
     * @param imagePath 图片路径（http/https链接或本地路径）
     * @param isLogo 是否为Logo（Logo尺寸更小，占页面40%；普通图片占80%）
     */
    private static void addImageToDocument(Document document, PdfFont font, String imagePath, boolean isLogo) {
        try {
            ImageData imageData;
            if(!"".equals(imagePath)){
                // 区分网络图片与本地图片
                if (WEB_IMAGE_PATTERN.matcher(imagePath).matches()) {
                    log.info("加载网络图片：{}", imagePath);
                    imageData = ImageDataFactory.create(imagePath);
                } else {
                    log.info("加载本地图片：{}", imagePath);
                    imageData = ImageDataFactory.create(imagePath);
                }

                // 创建图片对象并设置尺寸
                Image image = new Image(imageData);
                float pageWidth = document.getPdfDocument().getDefaultPageSize().getWidth() - 80f; // 减去边距
                float scaleRatio = isLogo ? 0.4f : 0.8f; // Logo占40%宽度，普通图片占80%
                image.scaleToFit(pageWidth * scaleRatio, Float.MAX_VALUE); // 按宽度比例缩放，保持原图比例

                // 设置图片位置与边距
                image.setHorizontalAlignment(HorizontalAlignment.CENTER);
                image.setMarginTop(10f);
                image.setMarginBottom(10f);
                document.add(image);
            }else {
                addErrorText(document, font, "无法加载图片：" + imagePath);
            }

        } catch (MalformedURLException e) {
            log.error("图片路径格式错误：{}", imagePath, e);
            addErrorText(document, font, "图片路径无效：" + imagePath);
        } catch (IOException e) {
            log.error("图片加载失败：{}", imagePath, e);
            addErrorText(document, font, "无法加载图片：" + imagePath);
        }
    }

    /**
     * 创建通用表格（指定列宽）
     * @param columnWidths 列宽数组（百分比）
     * @param font 字体
     * @return 表格对象
     */
    private static Table createTable(float[] columnWidths, PdfFont font) {
        Table table = new Table(UnitValue.createPercentArray(columnWidths));
        table.setWidth(UnitValue.createPercentValue(90f));
        table.setHorizontalAlignment(HorizontalAlignment.CENTER);
        return table;
    }

    /**
     * 创建信息单元格（用于封面分类等场景）
     * @param text 单元格文本
     * @param font 字体
     * @return 单元格对象
     */
    private static Cell createInfoCell(String text, PdfFont font) {
        return new Cell().add(new Paragraph(text)
                .setFont(font)
                .setTextAlignment(TextAlignment.CENTER)
                .setFontSize(SUB_TITLE_FONT_SIZE)
                .setBold())
                .setHeight(60f)
                .setBorder(Border.NO_BORDER)
                .setBackgroundColor(ColorConstants.LIGHT_GRAY)
                .setMargin(5f);
    }

    /**
     * 向文档添加错误提示文本（红色）
     * @param document 文档对象
     * @param font 字体
     * @param errorMsg 错误信息
     */
    private static void addErrorText(Document document, PdfFont font, String errorMsg) {
        Paragraph errorPara = new Paragraph(errorMsg)
                .setFont(document.getPdfDocument().getDefaultFont())
                .setFontColor(ColorConstants.RED);
        document.add(errorPara);
    }
}
